import random
import math
import Parameter

class IndividuoReal(object):
    """description of class"""

    parametros = []
    numParametros = 30
    alfa = 30
    maxVal = 1.0
    currentRank = 0

    diccionarioDominancia = []
    fitnessValues = []

    #----------------------------------------------------------------------
    def __init__(self, _funcionValores, numParametros, alfa, maxVal):
      self.diccionarioDominancia = []
      self.diccionarioDominancia.append(_funcionValores)
      self.fitnessValues = []
      self.numParametros = numParametros
      self.alfa = alfa
      self.maxVal = maxVal
      self.parametros = [0.0 for it in range(numParametros)]
      self.currentRank = 0

    #----------------------------------------------------------------------
    def RandomInit(self):
      for itParam in range(self.numParametros):
        self.parametros[itParam] = random.uniform(0, self.maxVal)
      self.GetFitnesVals()

    #----------------------------------------------------------------------
    def Distancia(self, individuo2):
      sum = 0
      for it in range(len(self.fitnessValues)):
        sum += (self.fitnessValues[it] - individuo2.fitnessValues[it])**2 
  
      return sum**0.5

    #----------------------------------------------------------------------
    def SetParametros(self, parametros):
      self.parametros = parametros
      self.fitnessValues = self.GetFitnesVals()
  
    #----------------------------------------------------------------------
    def GetFitnesVals(self):
      if len(self.fitnessValues) == 0:
        self.fitnessValues = self.diccionarioDominancia[0](self.parametros)
      
      return self.fitnessValues

    #----------------------------------------------------------------------
    def GetSharedFitness(self, nicheCount):
      return (sum(self.fitnessValues))/nicheCount

        
    #----------------------------------------------------------------------
    def CruzarCromosomas(self, pareja):
      params1 = []
      params2 = []
      #[x - a(y-x), y + a(y-x)]
      for it in range(self.numParametros):
        x = 0
        y = 0
        if self.parametros[it] > pareja.parametros[it]:
          y = self.parametros[it]
          x = pareja.parametros[it]
        else:
          x = self.parametros[it]
          y = pareja.parametros[it]

        params1.append(random.uniform(max(0,x - self.alfa*(y - x)), min(self.maxVal ,y + self.alfa*(y - x))))
        params2.append(random.uniform(max(0,x - self.alfa*(y - x)), min(self.maxVal ,y + self.alfa*(y - x))))

      hijo1 = IndividuoReal(self.diccionarioDominancia[0], self.numParametros, self.alfa, self.maxVal)
      hijo2 = IndividuoReal(self.diccionarioDominancia[0], self.numParametros, self.alfa, self.maxVal)
      hijo1.SetParametros(params1)
      hijo2.SetParametros(params2)

      return (hijo1, hijo2)
        
    #----------------------------------------------------------------------
    def Mutar(self):
      punto = random.randrange(self.numParametros -1)
      self.parametros[punto] = random.uniform(0, self.maxVal)
